package com.jy.event.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.parser.Feature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.jy.event.dao.PaymentDao;
import com.jy.event.domain.*;
import com.jy.event.httputil.HttpUtils;
import com.jy.event.httputil.RSASignature;
import com.jy.event.pay.request.PayRequest;
import com.jy.event.service.Payservice;
import com.jy.event.util.ObjectToMap;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.joda.time.LocalDate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * Created by lihu on 2017/12/18.
 */
@Slf4j
@Service
public class PayserviceImpl implements Payservice {


    private final static String ELECTRONIC_BILL_URL = "https://down.hstypay.com/gateway";

    String privateKey = "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBALSudzxTPNFRY8ql\n" +
            "xf2BCgCpfLq7POr3QVMpeXHhYu52toTx3FrRv82zTOiRY/PpiYIrxkpHYsv0ihG8\n" +
            "kV+Zm7xQ02VGhqo9wJaM0Oaw45B0rw8YjX7UhSxOimlB0/rqTV7nMWmMisfBrZPS\n" +
            "LCKPub83vOw1trjH7Ur4gAd+AiL1AgMBAAECgYAIzNaR4Zv8tfIeVKSoDDjof1jL\n" +
            "34LADvrnigWYPloLM00AfKc25TBqXGlKiopLvvwrkuY9h+yP8oEnDAAon9qt5Gwh\n" +
            "RvYZoztTI8k4UQY6O32Wr4Ic+SzKHBFW7YFpp5iKIdniOL1aBrSfxobJRTzu/1ZF\n" +
            "7+/zfLmMVW/hJ1GCoQJBAN29e5h5I4E9LDovRibS64RHbDQfn/TfaKLxuy+qrJuI\n" +
            "FHD7e4bqtMkSv50T7TzgGMOzWwHmiJIi7GBOBEKQGB8CQQDQmPwJ2iZjkvHFxTpY\n" +
            "Iv1Xt6mKimIjhCMzVv8Bc8yfb9GmAkZaWerdxANu9Et0/86IJV/xQXpC3D/hABSe\n" +
            "rjJrAkBpl/dIl79xpxjtqF+G04B2YLDFbZ31tYIVvnm+bE+ATWA2oXuktxZafoQj\n" +
            "ID8kcy832qxnDkpRFTJtdhmPPSFPAkEAxV5K8yN2uTZbDm5rouMQZEPB5fTDoKkx\n" +
            "CS2iQISJsr2BVxrF6E01vbjuKrh5AO3dQ9JhMgtrHAH7au/BktZtmwJBANJWWsj0\n" +
            "17wCumql7m8ZMytPPKNzTZLrihj+LqQGg35AYA9cD++FqEQV/gWzNoOHPJ6XTdOL\n" +
            "xmgv5G+x8u32mns=";

    @Autowired
    RestTemplate restTemplate;

    @Autowired
    PaymentDao paymentDao;


    @Override
    public ElectronicBill electronicBill(String storeId, String mchId, String key, String date, Date saveDate) {
        try {
            //初始化请求实体
            PayRequest payRequest = new PayRequest("pay.bill.merchant", StringUtils.trim(mchId));
            payRequest.setBill_date(date);
            Map objectAsMap = new ObjectMapper().convertValue(payRequest, Map.class);
            payRequest.setUpSign(objectAsMap, StringUtils.trim(key));

            String xml = xmlPost("https://down.hstypay.com/gateway", payRequest.toXML());
            if (null != xml) {
                //log.info(xml);
                String[] whole = xml.split("\r\n");
                int index = 0;
                for (int i = whole.length - 1; i >= 0; i--) {
                    if (whole[i].contains("总交易单数")) {
                        index = i;
                        break;
                    }
                }
                if (whole.length > index + 1) {
                    String result = whole[index + 1].replace("`", "");
                    String[] total = result.split(",");
                    log.info(Arrays.toString(total));
                    return new ElectronicBill(storeId, mchId, saveDate, total);
                } else {
                    log.error("electronicBill is error storeId:{}, date:{}, result:{}", storeId, date, xml);
                }
            }
        } catch (Exception ex) {
            log.error("electronicBill is error storeId:{}, date:{}, ex:{}", storeId, date, ex);
        }
        return null;
    }

    @Override
    public ElectronicBill suixinfuElectronicBill(StorePay storePay, String date, Date saveDate) throws Exception {
        String url = "https://openapi.tianquetech.com/capital/query/querySettlement";
        SuiXinFuBasePayReq<JSONObject> reqBean = new SuiXinFuBasePayReq<JSONObject>();
        reqBean.setOrgId("86146578");
        JSONObject reqData = new JSONObject();
        reqData.put("mno", storePay.getMchId()); //商户编号
        //下面两个至少传一个
        SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMdd");
        Date d1 = formatter.parse(date);
        Calendar dd = Calendar.getInstance();
        dd.setTime(d1);
        dd.add(Calendar.DAY_OF_MONTH, 1);//随行付取当天的账单需要加一天日期

        reqData.put("queryTime", formatter.format(dd.getTime())); //商户订单号
        reqBean.setReqData(reqData);
        String req = JSONObject.toJSONString(reqBean);
        System.out.println("req:" + req);
        //此处不要改变reqData里面值的顺序用LinkedHashMap
        HashMap reqMap = JSON.parseObject(req, LinkedHashMap.class, Feature.OrderedField);
        //组装加密串
        String signContent = RSASignature.getOrderContent(reqMap);
        System.out.println("拼接后的参数：" + signContent);
        //sign
        String sign = RSASignature.encryptBASE64(RSASignature.sign(signContent, privateKey));
        System.out.println("============签名:" + sign);
        reqMap.put("sign", sign);

        String reqStr = JSON.toJSONString(reqMap);
        System.out.println("请求参数:" + reqMap);
        System.out.println("请求参数:" + reqStr);
        String resultJson = HttpUtils.connectPostUrl(url, reqStr);
        System.out.println("返回信息：" + resultJson);
        //不要对reqData排序 所以用LinkedHashMap
        SuiXingFuResult suiXingFuResult = JSON.parseObject(resultJson, SuiXingFuResult.class);
        if (null == suiXingFuResult) return null;
        if (suiXingFuResult.isSuccess()) {
            ElectronicBill electronicBill = new ElectronicBill(storePay, saveDate, suiXingFuResult);
            return electronicBill;
        } else {
            log.error("electronicBill is error storeId:{}, date:{}, result:{}", storePay.getStoreId(), date, resultJson);
        }
        return null;
    }

    public String xmlPost(String url, String xml) throws IOException {
        HttpPost httpPost = new HttpPost(url);
        StringEntity entityParams = new StringEntity(xml, "utf-8");
        httpPost.setEntity(entityParams);
        httpPost.setHeader("Content-Type", "text/xml;charset=utf-8");
        HttpClient client = HttpClients.createDefault();
        HttpResponse response = client.execute(httpPost);
        if (response != null && response.getEntity() != null) {
            return EntityUtils.toString(response.getEntity(), "utf-8").trim();
        }
        return null;
    }


    @Override
    public void inspect(Store store) {
        try {
            LocalDate date = new LocalDate().plusDays(-1);
            //初始化请求实体
            PayRequest payRequest = new PayRequest("pay.bill.merchant",
                    store.getMchId(), date.toString("yyyyMMdd"));
            payRequest.setUpSign(ObjectToMap.objectToMap(payRequest), store.getKey());
            String xml = restTemplate.postForEntity(ELECTRONIC_BILL_URL, payRequest.toXML(), String.class).getBody();
            String str = new String(xml.getBytes("iso8859-1"), "UTF-8");
            str = str.replace("`", "");
            String[] whole = str.split("\n");
            List<Payment> payments = paymentDao.
                    findByStoreIdAndSuccessAndChannelInAndCreateTimeBetween(store.getId(),
                            true, Arrays.asList(PaymentChannel.WECHATPAY, PaymentChannel.ALIPAY),
                            date.toDate(), new LocalDate().toDate());
            Map<String, Payment> map = payments.stream().collect(Collectors.toMap(Payment::getId, payment -> payment));
            for (int i = 1; i < whole.length; i++) {
                String[] total = whole[i].split(",");
                if (total.length == 6) {
                    break;
                }
                String paymentId = total[8];
                Payment payment = map.get(paymentId);
                if (payment == null) {
                    log.error("========:{}", paymentId);
                } else {
                    map.remove(paymentId);
                }

            }
            map.forEach((key, value) ->
                    log.error("=======:{}", key)
            );

        } catch (Exception ex) {
            log.error("{}", ex);
        }


    }


}
